﻿using System;
using System.Collections.Generic;
using CIP4.Common;
using CIP4.Item;

namespace CIP4.Simple
{
    public interface ICIP4SliceType
    {
        ExternalIDType ParentId { get; set; }
        IBooleanValue SelectionExpression { get; set; }
        object ChildObject { get; set; }
        Type ParentType { get; }
        Dictionary<string, bool> PropertyMask { get; }
    }

    [CIP4Item(AddAllProperties = false)]
    public class CIP4SliceType<TChild, TParent> : ICIP4SliceType
    {
        /// <summary>
        /// Identifies the parent of the ChildObject. This will be populated after a GetItems call.
        /// It is not required on SaveItems, however only the first item encountered will be updated
        /// </summary>
        public ExternalIDType ParentId { get; set; }

        /// <summary>
        /// Only relevant for GetItems calls, identifies the child to be updated. 
        /// </summary>
        //public IBooleanValue ChildSelector { get; set; }

        /// <summary>
        /// On GetItems this is populated with the retreived child item.
        /// On SaveItems this is the item to be saved. If the value is null
        /// the selected child item will be deleted (or set to null)
        /// </summary>
        public TChild Child { get; set; }
        
        public object ChildObject
        {
            get { return Child; } 
            set { Child = (TChild) value; }
        }
        
        /// <summary>
        /// Type of the Parent item - populated using the generic type parameter
        /// </summary>
        public Type ParentType { get { return typeof(TParent); } }
        
        /// <summary>
        /// Properties to operate on - if a property path is present in the PropertyMask
        /// with the value true the property will be returned on GetItems, updated on SaveItems.
        /// If a property path is present in the PropertyMask with the value false, the 
        /// property will be set to null on SaveItems and not retreived on GetItems. 
        /// On GetItems if there is any value in the PropertyMask, any property path
        /// not present in the PropertyMask will not be retreived.
        /// </summary>
        public Dictionary<string, bool> PropertyMask { get; private set; }

        /// <summary>
        /// The selection expression used to select parent and child on SaveItems
        /// </summary>
        public IBooleanValue SelectionExpression { get; set; }

        public CIP4SliceType(TChild child, ExternalIDType parentID)
        {
            PropertyMask = new Dictionary<string, bool>();
            ParentId = parentID;
            Child = child;
        }
        public CIP4SliceType(TChild child, ExternalIDType parentID, IBooleanValue childIndex)
        {
            PropertyMask = new Dictionary<string, bool>();
            ParentId = parentID;
            SelectionExpression = childIndex;
            Child = child;
        }
        //public CIP4SliceType(TChild child, ExternalIDType parentID, IBooleanValue childIndex, IBooleanValue selectionExpression)
        //{
        //    SelectionExpression = selectionExpression;
        //    PropertyMask = new Dictionary<string, bool>();
        //    ParentId = parentID;
        //    ChildSelector = childIndex;
        //    Child = child;
        //}

        public override string ToString()
        {
            return string.Format("ParentId={0}, Child={1}, SelectionExpression={2}",
                                 ParentId == null ? "null" : ParentId.ToString(),
                                 ChildObject == null ? "null" : ChildObject.ToString(),
                                 SelectionExpression == null ? "null" : SelectionExpression.ToString());
        }
    }
}
